package cn.sdhuijin.utils;

import java.lang.reflect.Field;
import java.util.List;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

/**
 * 
 * @author houyc
 *
 * @param <T>
 */
public class DTO2EXCEL<T> {

	@SuppressWarnings("unchecked")
	public Workbook dto2excel(List<T> xls, String[] pro, String[] lab)
			throws Exception {
		T t = null;
		int CountColumnNum = lab.length;
		Workbook wb = new SXSSFWorkbook(100);
		Sheet sheet = wb.createSheet("sheet" + "");
		Row firstrow = sheet.createRow(0);
		Cell firstcell[] = new Cell[CountColumnNum];
		for (int j = 0; j < CountColumnNum; j++) {
			firstcell[j] = firstrow.createCell(j);
			firstcell[j].setCellValue(lab[j]);
		}
		for (int i = 0; i < xls.size(); i++) {
			Row row = sheet.createRow(i + 1);
			t = xls.get(i);
			Field f = null;
			Cell c = null;
			for (int colm = 0; colm < lab.length; colm++) {
				if (pro[colm].contains(".")) {
					String[] strs = pro[colm].split("\\.");
					f = getDeclaredField(t, strs[0]);
					f.setAccessible(true);
					t = (T) f.get(t);
					f = getDeclaredField(t, strs[1]);
					f.setAccessible(true);
					c = row.createCell(colm);
					if (f.get(t) != null) {
						c.setCellValue(f.get(t).toString());
					} else {
						c.setCellValue("");
					}
					t = xls.get(i);
				} else {
					f = getDeclaredField(t, pro[colm]);
					f.setAccessible(true);
					c = row.createCell(colm);
					if (f.get(t) != null) {
						c.setCellValue(f.get(t).toString());
					} else {
						c.setCellValue("");
					}
				}
			}
		}
		return wb;
	}

	/**
	 * 循环向上转型, 获取对象的 DeclaredField
	 * 
	 * @param object
	 *            : 子类对象
	 * @param fieldName
	 *            : 父类中的属性名
	 * @return 父类中的属性对象
	 */
	public static Field getDeclaredField(Object object, String fieldName) {
		Field field = null;
		Class<?> clazz = object.getClass();
		for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
			try {
				field = clazz.getDeclaredField(fieldName);
				// return field;
			} catch (Exception e) {
				// 这里甚么都不要做！并且这里的异常必须这样写，不能抛出去。
				// 如果这里的异常打印或者往外抛，则就不会执行clazz =
				// clazz.getSuperclass(),最后就不会进入到父类中了
			}
		}
		return field;
	}
}
